
var html;
var dataList = new ArrayList();  //总账单 包括信用卡和借记卡
var commMap = new HashMap();     //公共信息
var undone_new_balance = new BigDecimal("0");

var creditCardNo                                   //信用卡卡号
var creditCardAllData = new CreditCardAllData();   //信用卡对象
var creditCardNumberList = new ArrayList();        //信用卡列表
var indexOfCreditCard = 1;                         //信用卡序号
var creditBillDay;                                 //账单日
var debitCardNumber = 1;                     //借记卡序号
var debitCardNo;                             //借记卡卡号
var debitData = new CreditCardAllData();     //借记卡对象
var debitCardList = new ArrayList();         //借记卡列表
var lastPayment

var v4_cmbc_java_funcs = {

    openHomePage : function(){
        get("https://nper.cmbc.com.cn/pweb/static/login.html");
        var indexHtml = luaFuncs.getHtml2();
        storeDataToFile(context, indexHtml, "index.html");
        context.put("indexHtml", indexHtml);
    },
    checkProxyAvailable: function () {
        //展示窗口
        var indexHtml = context.get("indexHtml");
        //页面不为空
        if(StringUtils.isBlank(indexHtml)) {
            return false
        }
        var doc = Jsoup.parse(indexHtml)
        // 用户名输入框存在 密码框存在
        return doc.select("#writeUserId").size() > 0 && doc.select("#_ocx_passwordChar_login_pge").size() > 0

    },
    checkTargetWebsiteAvailable: function(){ return true },
    checkControlAvailable:function (){  return true },
    login: function() {
        inputUserName()   //输入用户名
        inputPassWord()   //输入密码
        inputImgCode()    //输入图片验证码
        verifyLogin()     //验证是否登录成功
        queryLoginInfo()  //获取登录后的信息
    },
    crawl:crawl,
    exitLogin: function () {}

}
function inputUserName(){
    var loginText = getLoginParams(context)[0];
    //输入用户名
    set_input_text_by_id("writeUserId", loginText);
    //检查短信验证码是否输入正常
    var loginTextInputResult = luaFuncs.checkIfInput("writeUserId", loginText);

    var isLoginInputCorrectFunc = function(loginTextInputResult) {
        return loginTextInputResult
    }

    var getLoginInputErrorMsgFunc = function(loginTextInputResult) {
        return "用户名未输入"
    }

    assertTrueOrThrowException(loginTextInputResult, isLoginInputCorrectFunc, getLoginInputErrorMsgFunc)
    logger.info("任务{}用户名输入成功", context.get(LUA_TASK_KEY))

}
function inputPassWord(){
    //输入密码
    show();//展示窗口
    var passWord = context.get(LUA_TASK_TOKEN)
    var inputPasswordResult = luaFuncs.input_minsheng_pwd(passWord);

    var isInputPasswordCorrectFunc = function(inputPasswordResult) {
        return inputPasswordResult
    }

    var getInputPasswordErrorMsgFunc = function(inputPasswordResult) {
        return "密码因控件输入错误"
    }

    assertTrueOrThrowException(inputPasswordResult, isInputPasswordCorrectFunc, getInputPasswordErrorMsgFunc)
    logger.info("任务{}密码输入成功", context.get(LUA_TASK_KEY))
    hide()
}
function inputImgCode(){


    var noNeedInputImgCode = Boolean.valueOf(luaFuncs.token_check_minsheng());

    logger.info("任务{}{}输入图片验证码", context.get(LUA_TASK_KEY), noNeedInputImgCode ? "不需要" : "需要")
    if(!noNeedInputImgCode){
        //输入验证码
        var captchaPath = get_image_by_id("_tokenImg");

        logger.info("任务{}图片验证码路径{}", context.get(LUA_TASK_KEY), captchaPath)
        var isCaptchaPathCorrectFunc = function(captchaPath) {
            return captchaPath !== null && captchaPath !== undefined && captchaPath !== 'path fail'
        }

        var getCaptchaPathErrorMsgFunc = function(captchaPath) {
            return "图片验证码获取失败"
        }
        assertTrueOrThrowException(captchaPath, isCaptchaPathCorrectFunc, getCaptchaPathErrorMsgFunc)
        logger.info("任务{}图片验证码获取成功", context.get(LUA_TASK_KEY))



        context.put(TASK_IMG_PATH, captchaPath);
        context.put(TASK_IMG_REGEX,"[0-9a-zA-Z]{4}");
        var imgCode = waitImgCodeBySecondsByJs(context,180,true,3);

        var isImgCodeCorrectFunc = function(imgCode) {
            return StringUtils.isNotBlank(imgCode) && imgCode.length === 4
        }

        var getImgCodeErrorMsgFunc = function(imgCode) {
            return "图片验证码错误"
        }
        assertTrueOrThrowException(imgCode, isImgCodeCorrectFunc, getImgCodeErrorMsgFunc)
        logger.info("任务{}图片验证码格式正确", context.get(LUA_TASK_KEY))

        set_input_text_by_id("_vTokenName", imgCode);
        var imgCodeInputResult = luaFuncs.checkIfInput("_vTokenName", imgCode);

        var isImgCodeInputCorrectFunc = function(imgCodeInputResult) {
            return imgCodeInputResult
        }

        var getImgCodeInputErrorMsgFunc = function(imgCodeInputResult) {
            return "图片验证码未输入"
        }
        assertTrueOrThrowException(imgCodeInputResult, isImgCodeInputCorrectFunc, getImgCodeInputErrorMsgFunc)
        logger.info("任务{}图片验证码输入成功", context.get(LUA_TASK_KEY))

    }
}
function verifyLogin(){

    logger.info("任务{}点击登录按钮并获取登录结果", context.get(LUA_TASK_KEY))
    //点击登录
    var loginResult = JSON.parse(luaFuncs.clickLoginButtonAndGetLoginResult())
    // var loginResult = JSON.parse("{\"status\": false, \"errorMsg\":\"未知错误\"}")
    storeDataToFile(context, loginResult, "loginResult.json")
    var loginResultHtml = luaFuncs.getHtml2()
    storeDataToFile(context, loginResultHtml, "loginResult.html")
    context.put("loginResultHtml", loginResultHtml);
    var isLoginCorrectFunc = function(loginResult) {
        if(!loginResult.get("status")){
            //保存错误页面和截图
            luaFuncs.saveHtmlAndImageFunc("clickLogin")
        }
        return loginResult.get("status")
    }
    var getLoginErrorMsgFunc = function(loginResult) {
        var errorMsg = loginResult.get("errorMsg")
        errorMsg = StringUtils.isNotBlank(errorMsg) ? errorMsg : "登录超时";
        if (errorMsg.contains("登录超时")){
            //保存错误页面和截图
            luaFuncs.saveHtmlAndImageFunc("clickLogin")
            var loginReusltHtml = context.get("loginResultHtml");
            if(loginReusltHtml.contains("个人网上银行登录密码修改")){
                errorMsg = "您还未设置查询/登录密码，请先登录官网设置";
            }
            if(loginReusltHtml.contains("个人网上银行首次登录")){
                errorMsg = "您需要完善登录信息,请先到官网进行登录";
            }
        }
        return errorMsg;

    }
    assertTrueOrThrowException(loginResult, isLoginCorrectFunc, getLoginErrorMsgFunc)
    logger.info("任务{}登录成功", context.get(LUA_TASK_KEY))

}
function queryLoginInfo(){
    var firstHtmlAfterLogin = luaFuncs.getHtml2()
    storeDataToFile(context, firstHtmlAfterLogin, "firstHtmlAfterLogin.html")

    var doc = Jsoup.parse(firstHtmlAfterLogin);

    var isfirstTimeLoginFunc = function(doc) {
        logger.info("任务{} title = {}", context.get(LUA_TASK_KEY), doc.select("title").text())
        return !equals(doc.select("title").text(), "中国民生银行网上银行首次登录")
    }

    var getfirstTimeLoginMsgFunc = function(doc) {
        logger.error("任务{}该账户首次登录", context.get(LUA_TASK_KEY))
        return "您需要完善登录信息,请先到官网进行登录"
    }
    assertTrueOrThrowException(doc, isfirstTimeLoginFunc, getfirstTimeLoginMsgFunc)
    logger.info("任务{}该账户非首次登录", context.get(LUA_TASK_KEY))
}

/**
 * 开始抓取流程---信用卡借记卡一起抓取
 */
function crawl()  {
    getCreditCardList();
    getDebitCardList();
    if(context.get("noDebitCard") &&  context.get("noCreditCard")) {
        throwBankExceptionByErrorCode(BALO_20304_30)
    }
    context.put("all_data", dataList);
    logger.info("CMBC taskKey:{},抓取卡信息成功！", context.get(LUA_TASK_KEY));
}
function getCreditCardList(){
    queryCreditCardList();//抓取卡列表
    dealCreditCardList(); //解析卡列表
    crawlCreditApp();     //解析卡信息
}

//获取信用卡列表信息
function queryCreditCardList(){
    logger.info("CMBC task：{},开始抓取信用卡",context.get(LUA_TASK_KEY))
    var cardListUrl = "https://nper.cmbc.com.cn/pweb/QryCreditAcNo.do";
    var paramsMap1 = new HashMap();
    paramsMap1.put("uri", "/pweb/QryCreditAcNo.do");
    paramsMap1.put("currentIndex", "0");
    var cardListInfo = requestUrlByPost(cardListUrl, paramsMap1);
    if (cardListInfo.contains("return is null")||cardListInfo.equals("")) {
        throwBankExceptionByErrorCode(BALO_20304_30)
    }
    storeDataToFile(context, cardListInfo, "信_"+Integer.parseInt(indexOfCreditCard)+"_cardList.html")
    context.put("credit_cardListInfo",cardListInfo)
}
//处理信用卡列表信息
function dealCreditCardList(){
    var cardListInfo = context.get("credit_cardListInfo")
    var cardMap = JSON.parse(cardListInfo);
    var cardList = cardMap.List;
    if(null != cardList && cardList.size() > 0){
        logger.info("民生银行信用卡 taskKey:{}，获取的卡列表数量：{}", context.get(LUA_TASK_KEY),cardList.size());
        for each(var cardMap1 in cardList){
            var cardNo = cardMap1.AcNo.toString();
            if(StringUtils.isNotBlank(cardNo)){
                creditCardNumberList.add(cardNo);
                commMap.put("AcNo", cardNo);
            }
        }
    }else{
        logger.info("民生银行信用卡列表请求为空，该用户尚无信用卡信息，taskKey:{}",context.get(LUA_TASK_KEY));
        context.put("noCreditCard", true)
    }
}
//解析信用卡信息
function crawlCreditApp(){
    for (var i = 0; i < creditCardNumberList.size(); i++) {
        //卡序号（第几张卡）
        logger.info("CMBC taskkey：{}，执行第{}张卡账单信息的抓取",context.get(LUA_TASK_KEY),Integer.parseInt(indexOfCreditCard))
        //存放卡号信息
        creditCardNo = creditCardNumberList.get(i)
        //信用卡信息
        creditCardAllData = new CreditCardAllData();
        var bills = new ArrayList();
        var deposits = new ArrayList();
        //账单信息
        creditCardAllData.setBills(bills);
        //存款信息，信用卡无此项
        creditCardAllData.setDeposits(deposits);
        queryBasicCardInfo()           //抓取基本信息
        dealBasicCardInfo()            //解析基本信息
        queryUnDoneBills()             //获取处理未出账单
        queryDoneBills()               //获取处理已出账单
        setLastBalanceForBill()        //抓取并保存分期历史交易
        dataList.add(creditCardAllData)
        indexOfCreditCard++
    }
}
//获取基本信息
function queryBasicCardInfo(){
    logger.info("CMBC taskkey：{}，开始抓取第{}张信用卡基本信息...",context.get(LUA_TASK_KEY),Integer.parseInt(indexOfCreditCard))
    var baseInfoUrl = "https://nper.cmbc.com.cn/pweb/LoginUserInfo.do?_=1.6";
    var baseInfo = requestUrlByGet(baseInfoUrl);
    storeDataToFile(context, baseInfo, "信_"+Integer.parseInt(indexOfCreditCard)+"_basicInfo.html")
    context.put("baseInfo",baseInfo)
    //获取有关账户的字段信息
    logger.info("CMBC taskkey：{}，开始抓取第{}张信用卡账户的字段信息...",context.get(LUA_TASK_KEY),Integer.parseInt(indexOfCreditCard))
    var userInfoUrl = "https://nper.cmbc.com.cn/pweb/userCredit.do?_=1.6";
    var userInfo = requestUrlByGet(userInfoUrl);
    storeDataToFile(context, userInfo, "信_"+Integer.parseInt(indexOfCreditCard)+"_userInfo.html")
    context.put("userInfo",userInfo)
    logger.info("CMBC taskkey：{}，开始抓取第{}张信用卡账户信息...",context.get(LUA_TASK_KEY),Integer.parseInt(indexOfCreditCard))
    var paramsMap = new HashMap();
    var accountInfoUrl = "https://nper.cmbc.com.cn/pweb/CreditUserInfoQryTrans.do";
    var accountInfo = requestUrlByGet(accountInfoUrl, paramsMap);
    storeDataToFile(context, accountInfo, "信_"+Integer.parseInt(indexOfCreditCard)+"_account.html")
    context.put("accountInfo",accountInfo)
}
//处理基本信息
function dealBasicCardInfo() {
    //设置基本信息
    creditCardAllData.setBankName("民生银行");
    creditCardAllData.setCardType("信用卡");
    creditCardAllData.setCardId(UUID.randomUUID().toString());
    if(null != creditCardNo && !"".equals(creditCardNo)){
        creditCardAllData.setFullCardNum(creditCardNo);
        if(creditCardNo.length() >= 4 ){
            var strsub =creditCardNo.substring(creditCardNo.length() - 4);
            creditCardAllData.setCardNum(strsub);      //卡号后四位
        }
    }
    var baseInfo = context.get("baseInfo")
    var userInfo = context.get("userInfo")
    var accountInfo = context.get("accountInfo")
    try {
        logger.info("CMBC taskkey：{}，开始解析第{}张信用卡账户的字段信息...",context.get(LUA_TASK_KEY),Integer.parseInt(indexOfCreditCard))
        var fieldMap =  JSON.parse(userInfo);
        var customerList =  fieldMap.CreditInfo;
        if(null != customerList && customerList.size() != 0){
            for each( var singleMap in customerList){
                if(singleMap == customerList.get(0)){
                    var customerMap =  singleMap;
                    var creditAcType =  customerMap.CREDITACTYPE;
                    commMap.put("creditAcType", creditAcType);
                }
            }
        }
        logger.info("CMBC taskkey：{}，开始解析第{}张信用卡用户基本信息...",context.get(LUA_TASK_KEY),Integer.parseInt(indexOfCreditCard))
        var baseInfoMap = JSON.parse(baseInfo);
        var resultMap =  baseInfoMap.userInfo;
        if(resultMap != null && resultMap.size() > 0 ){
            var name_on_card =  resultMap.CIFNAME;    //持卡人姓名
            creditCardAllData.setNameOnCard(name_on_card);
        }
        logger.info("CMBC taskkey：{}，开始解析第{}张信用卡用户账号信息...",context.get(LUA_TASK_KEY),Integer.parseInt(indexOfCreditCard))
        var accountInfoMap = JSON.parse(accountInfo);
        creditBillDay =  accountInfoMap.BillDay;        //账单日
        commMap.put("BillDay",creditBillDay);
        var list = accountInfoMap.List;
        if( null != list && list.size() > 0){
            var userInfoMap = list.get(0);
            if(null != userInfoMap && userInfoMap.size() > 0){
                var credit_limit =  userInfoMap.CreTLmit;
                creditCardAllData.setCreditLimit(new BigDecimal(credit_limit));   //信用卡额度
                commMap.put("credit_limit", credit_limit);

                var balance =  userInfoMap.NUBLmit;
                creditCardAllData.setBalance(new BigDecimal(balance));   //信用卡可用额度

                var cash_limit =  userInfoMap.CSCreLmit;
                creditCardAllData.setCashLimit(new BigDecimal(cash_limit));    //信用卡现金额度
                commMap.put("cash_limit", cash_limit);

                var cash_balance =  userInfoMap.CSUBLmit;
                creditCardAllData.setCashBalance(new BigDecimal(cash_balance));    //信用卡现金可用额度
            }
        }
    } catch (e) {
        logger.info("CMBC taskkey：{}，解析第{}张信用卡基本信息出错：{}",context.get(LUA_TASK_KEY),Integer.parseInt(indexOfCreditCard),e)
        statCaughtException(context, e);
    }
}
//获取并解析未出账单
function queryUnDoneBills(){
    try {
        var paramsMap = new HashMap();
        paramsMap.put("CreditAcType",  commMap.creditAcType);
        paramsMap.put("uri","/pweb/DisOutCreditBillQry.do" );
        paramsMap.put("BillFlag","2");
        paramsMap.put("currentIndex", "0");
        var billAllData = getUndoneBillData();
        var expenseList = billAllData.getShoppingSheets();
        var currentPage = 1;
        var number = 0;
        var orderIndex = 0;
        lastPayment = null
        while(true){
            if(Integer.parseInt(currentPage) > 1){
                paramsMap.put("currentIndex", (Integer.parseInt(currentPage)-1)*10);
                paramsMap.put("pageNo", Integer.parseInt(currentPage));
                paramsMap.put("recordNumber", commMap.recordNumber);
            }
            var undoneBillUrl = "https://nper.cmbc.com.cn/pweb/DisOutCreditBillQry.do";
            var undoneBill = requestUrlByPost(undoneBillUrl, paramsMap);
            if(StringUtils.isBlank(undoneBill)){
                logger.info("CMBC taskKey:{}, 未出账单未找到符合条件的记录", context.get(LUA_TASK_KEY));
                break;
            }else{
                var undoneBillMap = JSON.parse(undoneBill);
                var errorMsg = undoneBillMap.errmsg;
                if(StringUtils.isNotBlank(errorMsg)){
                    logger.info("CMBC taskKey:{}, 未出账单未找到符合条件的记录,页面信息：{}", context.get(LUA_TASK_KEY),errorMsg);
                    storeDataToFile(context, undoneBill,"信_"+Integer.parseInt(indexOfCreditCard)+"_undone_bills_"+Integer.parseInt(currentPage)+".html")
                    break;
                }else{
                    logger.info("CMBC taskKey:{}, 获取未出账单,本月第{}页",
                        context.get(LUA_TASK_KEY),Integer.parseInt(currentPage));
                    storeDataToFile(context, undoneBill, "信_"+Integer.parseInt(indexOfCreditCard)+"_undone_bills_"+Integer.parseInt(currentPage)+".html")
                    var recordNumber = String.valueOf(parseInt(undoneBillMap.recordNumber));
                    Integer.parseInt(currentPage++);
                    commMap.put("recordNumber", recordNumber);
                    var singleList =  undoneBillMap.List;
                    var pageNumber = undoneBillMap.pageNumber;
                    if( null != singleList && singleList.size() > 0 && Integer.parseInt(currentPage) <= pageNumber+1){
                        for each(var payMap in singleList){
                            number=number+1;
                            //账单详情
                            var expense = getExpenseCredit(payMap, ++orderIndex);
                            expenseList.add(expense);
                            var amout_money =  expense.getAmountMoney();    //(计算)账单总金额
                            undone_new_balance = undone_new_balance.add(amout_money);
                            var new_charges = billAllData.getNewCharges();
                            if(amout_money.compareTo(BigDecimal.ZERO) == 1){
                                if(null == new_charges){
                                    new_charges = new BigDecimal("0");
                                }
                                billAllData.setNewCharges(new_charges.add(amout_money));
                            }
                        }
                        billAllData.setLastPayment(lastPayment);
                    }else{
                        break;
                    }
                }
            }
        }
        if(number>0){
            creditCardAllData.getBills().add(billAllData);
        }
    } catch (e) {
        logger.error("CMBC taskKey:{}, 获取解析未出账单出错:{}", context.get(LUA_TASK_KEY), e);
        statCaughtException(context, e);
    }
}
//单元测试所需代码  解析未出账单
function analysisUndownBill(billAllData,expenseList,page){
    var orderIndex = (page-1)*10;
    if(page<=1){
        lastPayment = null
    }
    var undoneBill = context.get("undoneBill")
    if(StringUtils.isBlank(undoneBill)){
        logger.info("CMBC taskKey:{}, 未出账单未找到符合条件的记录", context.get(LUA_TASK_KEY));
        return false;
    }else{
        var undoneBillMap = JSON.parse(undoneBill);
        var errorMsg = undoneBillMap.errmsg;
        if(StringUtils.isNotBlank(errorMsg)){
            logger.info("CMBC taskKey:{}, 未出账单未找到符合条件的记录,页面信息：{}", context.get(LUA_TASK_KEY),errorMsg);
            return false;
        }else{
            logger.info("CMBC taskKey:{}, 获取未出账单，本月第{}页",
                context.get(LUA_TASK_KEY),Integer.parseInt(page));
            var recordNumber = String.valueOf(parseInt(undoneBillMap.recordNumber));
            commMap.put("recordNumber", recordNumber);
            var singleList =  undoneBillMap.List;
            var pageNumber = undoneBillMap.pageNumber;
            if( null != singleList && singleList.size() > 0){
                for each(var payMap in singleList){
                    //账单详情
                    var expense = getExpenseCredit(payMap,Integer.parseInt(++orderIndex));
                    expenseList.add(expense);
                    var amout_money =  expense.getAmountMoney();    //(计算)账单总金额
                    undone_new_balance = undone_new_balance.add(amout_money);
                    var new_charges = billAllData.getNewCharges();
                    if(amout_money.compareTo(BigDecimal.ZERO) == 1){
                        if(null == new_charges){
                            new_charges = new BigDecimal("0");
                        }
                        billAllData.setNewCharges(new_charges.add(amout_money));
                    }
                }
                billAllData.setLastPayment(lastPayment);
                return true;
            }else{
                return false;
            }
        }
    }
}
//获取并解析已出账单
function queryDoneBills() {
    try {
        var sixMonth = getSixMonth(creditBillDay);
        var creditIndexOfBill = 0;
        for(var i=0; i<sixMonth.size(); i++){
            var billDate = sixMonth.get(i);
            var paramsMap = new HashMap();
            paramsMap.put("CreditAcType",  commMap.creditAcType);
            paramsMap.put("CurrencyFlag", "L");
            paramsMap.put("BillDate", billDate);
            paramsMap.put("BillDay",creditBillDay);
            var doneBillUrl = "https://nper.cmbc.com.cn/pweb/CreditBillTitleQry.do";
            var doneBill = requestUrlByPost(doneBillUrl, paramsMap);
            var doneBillMap =  JSON.parse(doneBill);
            var errmsg = doneBillMap.errmsg;
            var billAllData = new BillAllData();
            billAllData.setBillType("DONE");
            billAllData.setBankName("民生银行");
            billAllData.setUsdNewBalance(null);//美元相关
            billAllData.setUsdMinPayment(null);
            billAllData.setUsdLastBalance(null);
            billAllData.setUsdLastPayment(null);
            billAllData.setUsdNewCharges(null);
            billAllData.setUsdInterest(null);
            billAllData.setUsdCreditLimit(null);
            billAllData.setUsdCashLimit(null);
            billAllData.setBillId(UUID.randomUUID().toString());
            var bill_Month = "20"+ billDate;
            billAllData.setBillMonth(TimeUtil.getTimeStr(TimeUtil.getTime(bill_Month, "yyyyMM"), "yyyy-MM"));
            billAllData.setCreditLimit(new BigDecimal(commMap.credit_limit.toString()));   //信用卡额度
            billAllData.setCashLimit(new BigDecimal(commMap.cash_limit.toString()));       //预借现金额度
            creditIndexOfBill++
            storeDataToFile(context, doneBill,
                "信_"+Integer.parseInt(indexOfCreditCard)+"_doneBills_"+Integer.parseInt(creditIndexOfBill)+".html");
            if("".equals(errmsg) || errmsg == null){
                logger.info("CMBC  taskKey:{}, 已出账单title,月份：{},总排序第{}页",
                    context.get(LUA_TASK_KEY),billDate,Integer.parseInt(creditIndexOfBill));
                var bill_Date = doneBillMap.BillDate;
                var AcNo = doneBillMap.AcNo;
                if(null != AcNo && !"".equals(AcNo) && null == commMap.get(AcNo)){
                    commMap.put("AcNo", AcNo);
                }
                if(!"".equals(bill_Date)){
                    billAllData.setBillDate(yyyy_MM_dd_PARSER.parse(bill_Date));
                }else{
                    var bill_date = bill_Month +  creditBillDay;
                    billAllData.setBillDate(
                        yyyy_MM_dd_PARSER.parse(TimeUtil.getTimeStr(TimeUtil.getTime(bill_date, "yyyyMMdd"), "yyyy-MM-dd")));
                }
                billAllData.setPaymentDueDate(yyyy_MM_dd_PARSER.parse(doneBillMap.RepayLimitDate));          //到期还款日
                billAllData.setNewBalance(new BigDecimal(String.valueOf(doneBillMap.CurrentNeedPayAmtS)));   // CurrentNeedPayAmt 本期账单金额
                billAllData.setMinPayment(new BigDecimal(String.valueOf(doneBillMap.MinRepayLimit)));        //最低还款额
                billAllData.setLastBalance(new BigDecimal(String.valueOf(doneBillMap.LastPeriodBillAmt)));   //上期账单金额
                var last_payment = String.valueOf(doneBillMap.AlreadyPayAmt);
                billAllData.setLastPayment(new BigDecimal(last_payment).multiply(new BigDecimal("-1")));     //上期还款金额
                billAllData.setNewCharges(new BigDecimal(String.valueOf(doneBillMap.CurrentperiodBillAmt))); //本期新增款额
                var payment_day = doneBillMap.RepayLimitDate;
                billAllData.setPaymentDueDate(yyyy_MM_dd_PARSER.parse(payment_day));
                billAllData.setInterest(new BigDecimal(String.valueOf(doneBillMap.CycleInterest)));
                billAllData.setShoppingSheets(new ArrayList());//账单详情
                //抓取及保存账单详情
            }else{
                logger.info("CMBC taskKey:{},已出账单title---本月无title信息，月份：{},总排序第{}页",
                    context.get(LUA_TASK_KEY),billDate,Integer.parseInt(creditIndexOfBill));
                billAllData.setInterest(null);
                billAllData.setLastBalance(null);
                billAllData.setLastPayment(null);
                billAllData.setMinPayment(null);
                billAllData.setNewBalance(null);
                billAllData.setNewCharges(null);
            }
            saveDoneBillsDetail(billAllData, billDate, i);
        }
    } catch (e) {
        logger.error("民生银行抓取并保存已出账单title时出错，taskKey:{} 错误问题: {}",context.get(LUA_TASK_KEY),e);
    }
}

//单元测试解析已出账单
function analysisDownBillsTest(billAllData,billDate,page){
    var doneBill = context.get("doneBill")
    var doneBillMap =  JSON.parse(doneBill);
    var errmsg = doneBillMap.errmsg;
    billAllData.setBillType("DONE");
    billAllData.setBankName("民生银行");
    //美元相关
    billAllData.setUsdNewBalance(null);
    billAllData.setUsdMinPayment(null);
    billAllData.setUsdLastBalance(null);
    billAllData.setUsdLastPayment(null);
    billAllData.setUsdNewCharges(null);
    billAllData.setUsdInterest(null);
    billAllData.setUsdCreditLimit(null);
    billAllData.setUsdCashLimit(null);
    billAllData.setBillId(UUID.randomUUID().toString());
    var bill_Month = "20"+ billDate;
    billAllData.setBillMonth(getDateStr(bill_Month,"yyyyMM","yyyy-MM"));
    billAllData.setCreditLimit(new BigDecimal(commMap.credit_limit.toString()));   //信用卡额度
    billAllData.setCashLimit(new BigDecimal(commMap.cash_limit.toString()));       //预借现金额度

    if("".equals(errmsg) || errmsg == null){
        logger.info("CMBC  taskKey:{}, 已出账单title,开始时间：{},总排序第{}页",context.get(LUA_TASK_KEY),billDate,Integer.parseInt(page));
        var bill_Date = doneBillMap.BillDate;
        var AcNo = doneBillMap.AcNo;
        if(null != AcNo && !"".equals(AcNo) && null == commMap.get(AcNo)){
            commMap.put("AcNo", AcNo);
        }
        if(!"".equals(bill_Date)){
            billAllData.setBillDate(yyyy_MM_dd_PARSER.parse(bill_Date));
        }else{
            var bill_date = bill_Month +  creditBillDay;
            billAllData.setBillDate(getDate("bill_date","yyyyMMdd"));
        }
        billAllData.setPaymentDueDate(yyyy_MM_dd_PARSER.parse(doneBillMap.RepayLimitDate));          //到期还款日
        billAllData.setNewBalance(new BigDecimal(String.valueOf(doneBillMap.CurrentNeedPayAmtS)));   // CurrentNeedPayAmt 本期账单金额
        billAllData.setMinPayment(new BigDecimal(String.valueOf(doneBillMap.MinRepayLimit)));        //最低还款额
        billAllData.setLastBalance(new BigDecimal(String.valueOf(doneBillMap.LastPeriodBillAmt)));   //上期账单金额
        var last_payment = String.valueOf(doneBillMap.AlreadyPayAmt);
        billAllData.setLastPayment(new BigDecimal(last_payment).multiply(new BigDecimal("-1")));     //上期还款金额
        billAllData.setNewCharges(new BigDecimal(String.valueOf(doneBillMap.CurrentperiodBillAmt))); //本期新增款额
        var payment_day = doneBillMap.RepayLimitDate;
        billAllData.setPaymentDueDate(yyyy_MM_dd_PARSER.parse(payment_day));
        billAllData.setInterest(new BigDecimal(String.valueOf(doneBillMap.CycleInterest)));
        billAllData.setShoppingSheets(new ArrayList());//账单详情
        //抓取及保存账单详情
    }else{
        logger.info("CMBC taskKey:{},已出账单title---本月无title信息，开始时间：{},总排序第{}页",
            context.get(LUA_TASK_KEY),billDate,Integer.parseInt(page));
        billAllData.setInterest(null);
        billAllData.setLastBalance(null);
        billAllData.setLastPayment(null);
        billAllData.setMinPayment(null);
        billAllData.setNewBalance(null);
        billAllData.setNewCharges(null);
    }
}
//单元测试解析已出账单明细
function analysisDownBillDetail(billAllData, billDate,page){
    var orderIndex = (page-1)*10;
    var doneBillDetail = context.get("doneBillDetail")
    if(null == doneBillDetail || "".equals(doneBillDetail)){
        logger.info("民生银行taskKey:{},账单时间：{},已出账单未找到符合条件的详情记录", context.get(LUA_TASK_KEY),billDate);
        return false;
    }else{
        var doneBillDetailMap =  JSON.parse(doneBillDetail);
        var errorMsg = doneBillDetailMap.errmsg;
        if(null != errorMsg && !"".equals(errorMsg)){
            logger.info("民生银行已出账单详情，taskKey:{}," +
                "账单时间：{},本月第{}页,已出账单未找到符合条件的详情记录,页面信息：{}",
                context.get(LUA_TASK_KEY),billDate,Integer.parseInt(page),errorMsg);
            return false;
        }else{
            logger.info("民生银行已出账单详情，taskKey:{}," +
                "账单时间：{},本月第{}页",context.get(LUA_TASK_KEY),billDate,Integer.parseInt(page));
            var recordNumber = doneBillDetailMap.recordNumber;
            commMap.put("recordNumber", recordNumber);
            var pageNumber =  doneBillDetailMap.pageNumber;
            var currentPayRecordsDetail =  doneBillDetailMap.List;
            if(null == currentPayRecordsDetail || currentPayRecordsDetail.size()==0){
                return false;
            }else{
                for each(var payMap in currentPayRecordsDetail){
                    var expense = getExpenseCredit(payMap,Integer.parseInt(++orderIndex));
                    billAllData.getShoppingSheets().add(expense);
                    getInstallmentsFromExpense(expense,billAllData);
                }
                return true;
            }
        }
    }
}
//抓取并保存分期历史交易
function setLastBalanceForBill(){
    try {
        var new_balance = creditCardAllData.getBills().get(1).getNewBalance();
        var usd_new_balance = creditCardAllData.getBills().get(1).getUsdNewBalance();
        if(null == new_balance){
            new_balance = new BigDecimal("0");
        }
        if(null == usd_new_balance){
            usd_new_balance = new BigDecimal("0");
        }
        creditCardAllData.getBills().get(0).setNewBalance(new_balance.add(undone_new_balance));
        if(!"".equals(new_balance)){
            creditCardAllData.getBills().get(0).setLastBalance(new_balance);
        }else{
            creditCardAllData.getBills().get(0).setLastBalance(null);
        }
        if(!"".equals(usd_new_balance)){
            creditCardAllData.getBills().get(0).setUsdLastBalance(usd_new_balance);
        }else{
            creditCardAllData.getBills().get(0).setUsdLastBalance(null);
        }
    } catch (e) {
        statCaughtException(context, e);
        logger.error("CMBC taskkey:{},抓取并保存分期历史交易出错：{}",context.get(LUA_TASK_KEY),e);
    }
}
//请求url重试策略，目前重试3次
function requestUrlByGet(url){
    logger.info("CMBC taskkey：{}，get方式初次请求url：{}",context.get(LUA_TASK_KEY),url)
    var content =  ajax_get(url)
    var times = 1
    while(StringUtils.isBlank(content)&&times<=3){
        logger.info("CMBC taskkey：{}，get请求返回的content:{}",context.get(LUA_TASK_KEY),content)
        logger.info("CMBC taskkey：{}，重试第{}次get方式请求url:{}",context.get(LUA_TASK_KEY),times,url)
        Thread.sleep(3000)
        times++;
        content =  ajax_get(url)
    }
    return content;
}
//请求url重试策略，目前重试3次
function requestUrlByPost(url,map){
    logger.info("CMBC taskkey：{}，post请求初次请求url：{}",context.get(LUA_TASK_KEY),url)
    var content =  ajax_post(url,map)
    var times = 1
    while(StringUtils.isBlank(content) &&times<=3){
        logger.info("CMBC taskkey：{}，post请求返回的content:{}",context.get(LUA_TASK_KEY),content)
        logger.info("CMBC taskkey：{}，重试第{}次post方式请求url:",context.get(LUA_TASK_KEY),times,url)
        Thread.sleep(3000)
        times++;
        content =  ajax_post(url,map)
    }
    return content;
}

function getDebitCardList(){
    queryDebitCardList();
    dealDebitCardList();
    crawlDebitApp();
}
function queryDebitCardList(){
    logger.info("CMBC task：{},开始抓取借记卡...",context.get(LUA_TASK_KEY))
    var cardListUrl = "https://nper.cmbc.com.cn/pweb/AcListQrys.do";
    var paramsMap1 = new HashMap();
    paramsMap1.put("uri", "/pweb/AcListQrys.do");
    paramsMap1.put("currentIndex", "0");
    var cardListInfo = requestUrlByPost(cardListUrl, paramsMap1);
    if (cardListInfo.contains("return is null")||cardListInfo.equals("")) {
        throwBankExceptionByErrorCode(BALO_20304_30)
    }
    storeDataToFile(context, cardListInfo, "借_"+Integer.parseInt(debitCardNumber)+"_cardList.html")
    context.put("debit_cardListInfo",cardListInfo)
}
function dealDebitCardList(){
    var cardListInfo = context.get("debit_cardListInfo")
    var cardMap = JSON.parse(cardListInfo);
    var cardList = cardMap.List;
    if(null != cardList && cardList.size() > 0 ){
        logger.info("CMBC taskKey:{}, 抓取借记卡数量:{}", context.get(LUA_TASK_KEY),cardList.size());
        for each(var cardMap1 in cardList){
            var cardNo = cardMap1.AcNo.toString();
            if(StringUtils.isNotBlank(cardNo)){
                debitCardList.add(cardNo);
                commMap.put("AcNo", cardNo);
            }
        }
    }else{
        context.put("noDebitCard", true)
        logger.info("CMBC taskKey:{},借记卡列表为空，该用户尚无借记卡...",context.get(LUA_TASK_KEY));
    }
}
function crawlDebitApp(){
    for (var i = 0; i < debitCardList.size(); i++) {
        //卡序号（第几张卡）
        logger.info("CMBC 借记卡 taskkey：{}，执行第{}张卡账单信息的抓取...",context.get(LUA_TASK_KEY),Integer.parseInt(debitCardNumber))
        //存放卡号信息
        debitCardNo = debitCardList.get(i)
        //借记卡信息
        debitData = new CreditCardAllData();
        var bills = new ArrayList();
        var deposits = new ArrayList();
        //账单信息
        debitData.setBills(bills);
        //存款信息，信用卡无此项
        debitData.setDeposits(deposits);
        queryDebitBasicCardInfo()           //抓取基本信息
        dealDebitBasicCardInfo()            //解析基本信息
        saveDepositsDebit()                 //保存存款信息
        saveBillsInfoDebit()               //保存交易流水信息
        dataList.add(debitData)
        debitCardNumber++
    }
}
//获取借记卡基本信息
function queryDebitBasicCardInfo(){
    logger.info("CMBC taskKey:{}, 开始抓取", context.get(LUA_TASK_KEY));
    //基本信息
    var paramsMap = new HashMap();
    var baseInfoUrl = "https://nper.cmbc.com.cn/pweb/AcListInitQry.do";
    var baseInfo = requestUrlByPost(baseInfoUrl, paramsMap);
    storeDataToFile(context, baseInfo, "借_"+Integer.parseInt(debitCardNumber)+"_basicInfo.html")
    context.put("baseInfo",baseInfo)
}
//解析借记卡基本信息
function dealDebitBasicCardInfo(){
    try {
        var baseInfo = context.get("baseInfo")
        var baseMap = JSON.parse(baseInfo);
        var balance =  baseMap.AvailBalTotal;
        debitData.setBalance(new BigDecimal(balance));   //借记余额
        var baseList =  baseMap.OList;
        if(null !== baseList && baseList.size() > 0){
            var userDetail = baseList.get(0);
            debitData.setCardId(UUID.randomUUID().toString());  //ID
            debitData.setCardType("借记卡");    //卡片类型（借记卡）
            debitData.setBankName("民生银行");
            debitData.setCashBalance(null);
            debitData.setCashLimit(null);
            debitData.setCreditLimit(null);
            var fullCardNum =  userDetail.AcNo;
            debitData.setFullCardNum(fullCardNum);   //完整卡号
            var cardNum = fullCardNum.substring(fullCardNum.length() - 4);
            debitData.setCardNum(cardNum);   //卡号后四位
            commMap.put("cardNum", cardNum);
            commMap.put("AcNo", fullCardNum);
            commMap.put("BankAcType", userDetail.BankAcType);
            var name =  userDetail.AcName;
            debitData.setNameOnCard(name); //持卡人
            commMap.put("AcName", name);
            var openBank =  userDetail.DeptName;
            debitData.setOpenBank(openBank);   //开户行
        }
    } catch (e) {
        logger.error("CMBC taskKey:{}, 借记卡在解析个人信息时出错:{}",context.get(LUA_TASK_KEY), e);
        statCaughtException(context, e);
    }


}
//保存存款信息
function saveDepositsDebit() {
    try {
        var currentPage = 1;
        var paramsMap = new HashMap();
        while(true){
            if(Integer.parseInt(currentPage) == 1){
                paramsMap.put("AcNo",commMap.AcNo);
                paramsMap.put("BankAcType", commMap.BankAcType);
            }else{
                paramsMap.put("uri", "/pweb/SubActsQry.do");
                paramsMap.put("currentIndex", (Integer.parseInt(currentPage)-1)*10);
                paramsMap.put("pageNo", Integer.parseInt(currentPage));
                paramsMap.put("recordNumber", String.valueOf(commMap.recordNumber));
            }

            var depositsUrl = "https://nper.cmbc.com.cn/pweb/SubActsQry.do";
            var depositsDetail = requestUrlByPost(depositsUrl, paramsMap);
            logger.info("CMBC taskKey:{}, 存款详情，第{}页",context.get(LUA_TASK_KEY),Integer.parseInt(currentPage));
            storeDataToFile(context, depositsDetail, "借_"+Integer.parseInt(debitCardNumber)+"_deposits_"+Integer.parseInt(currentPage)+".html")
            Integer.parseInt(currentPage++);
            var depositsMap = JSON.parse(depositsDetail);
            var pageNumber =  depositsMap.pageNumber;
            var recordNumber = depositsMap.recordNumber;
            commMap.put("recordNumber", recordNumber);
            var depositsList =  depositsMap.List;
            if(null == depositsList || depositsList.size() <= 0 || Integer.parseInt(currentPage) > pageNumber + 1){
                break;
            }else{
                for each(var depositsDetailMap in depositsList){
                    getDeposits(depositsDetailMap);
                    //debitData.getDeposits().add(deposits);
                }
            }
        }
    } catch (e) {
        logger.info("民生银行taskKey:{}, 存款详情出错:{}",context.get(LUA_TASK_KEY), e);
        statCaughtException(context, e);
    }

}
//单元测试逻辑
function analysisDepositsDebit(currentPage) {
    var depositsDetail = context.get("depositsDetail")
    logger.info("CMBC taskKey:{}, 存款详情，第{}页",context.get(LUA_TASK_KEY),Integer.parseInt(currentPage));
    var depositsMap = JSON.parse(depositsDetail);
    var pageNumber =  depositsMap.pageNumber;
    var recordNumber = depositsMap.recordNumber;
    commMap.put("recordNumber", recordNumber);
    var depositsList =  depositsMap.List;
    if(null == depositsList || depositsList.size() <= 0){
        return false;
    }else{
        for each(var depositsDetailMap in depositsList){
            getDeposits(depositsDetailMap);
        }
        return true;
    }
}
//单元测试
function anaysisSaveBillsDetail(billAllData,beginDate,endDate,page){
    var orderIndex = (page-1)*10;
    logger.info("民生银行借记卡交易流水，taskKey:{},开始时间：{}，结束时间：{}，本月第{}页",
        context.get(LUA_TASK_KEY),beginDate,endDate,Integer.parseInt(page));
    var billsDetail = context.get("billsDetail")
    var billsDetailMap =  JSON.parse(billsDetail);
    var currentDetailList = billsDetailMap.List;
    if(null == currentDetailList || currentDetailList.size() <= 0 ){
        logger.info("民生银行借记卡交易流水，taskKey:{},开始时间：{}，结束时间：{}，本月第{}页没有获取到信息",
            context.get(LUA_TASK_KEY),beginDate,endDate,Integer.parseInt(page));
        return false;
    }else{
        for each(var payMap in currentDetailList){
            billAllData.getShoppingSheets().add(getExpenseDebit(payMap,Integer.parseInt(++orderIndex)));
        }
        return true;
    }
}
//保存交易流水信息
function saveBillsInfoDebit() {
    try {
        var fst = getFirstSixMonthFirstDay();
        var lst = getBeforSixMonthLast();
        for(var i=0 ; i < 25 ; i++){
            var beginDate = fst.get(i);
            var endDate = lst.get(i);
            var billAllData = new BillAllData();
            billAllData.setBillType("");
            billAllData.setBillId(UUID.randomUUID().toString());
            billAllData.setBankName("民生银行");
            billAllData.setBillMonth(beginDate.substring(0, 7));
            if(i == 24){
                var billDate1 = beginDate.substring(0,8);
                billAllData.setBillDate(yyyy_MM_dd_PARSER.parse(billDate1 + "01"));
            }else{
                billAllData.setBillDate(yyyy_MM_dd_PARSER.parse(beginDate));
            }
            //账单详情
            billAllData.setShoppingSheets(new ArrayList());
            setValueForBill(billAllData);
            saveBillsDetail(billAllData, beginDate, endDate);
        }
    } catch (e) {
        logger.error("民生银行借记卡保存账单title信息时出错，taskKey:{}, e:{}",context.get(LUA_TASK_KEY), e);
        statCaughtException(context, e);
    }
}

function setValueForBill(billAllData){
    billAllData.setNewBalance(null);
    billAllData.setUsdNewBalance(null);
    billAllData.setMinPayment(null);
    billAllData.setUsdMinPayment(null);
    billAllData.setLastBalance(null);
    billAllData.setUsdLastBalance(null);
    billAllData.setUsdLastPayment(null);
    billAllData.setLastPayment(null);
    billAllData.setNewCharges(null);
    billAllData.setUsdNewCharges(null);
    billAllData.setInterest(null);
    billAllData.setUsdInterest(null);
    billAllData.setCreditLimit(null);
    billAllData.setUsdCreditLimit(null);
    billAllData.setCashLimit(null);
    billAllData.setUsdCashLimit(null);
}

//保存交易流水详情 ---  借记卡
function saveBillsDetail( billAllData, beginDate, endDate) {
    try {
        var currentPage = 1;
        var paramsMap = new HashMap();
        paramsMap.put("AcNo", commMap.AcNo);
        paramsMap.put("BankAcType", commMap.BankAcType);
        paramsMap.put("BeginDate", beginDate);
        paramsMap.put("EndDate", endDate);
        paramsMap.put("AcName", commMap.AcName);
        paramsMap.put("Remark", "-");
        paramsMap.put("Fee", "0.00");
        paramsMap.put("FeeRemark", "-");
        paramsMap.put("SubAcSeq", "0001");
        paramsMap.put("currentIndex", "0");
        paramsMap.put("uri", "/pweb/ActTrsQry.do");
        var number = 0;
        var orderIndex = 0;
        while(true){
            if(Integer.parseInt(currentPage) > 1){
                paramsMap.put("currentIndex", (Integer.parseInt(currentPage)-1)*10);
                paramsMap.put("pageNo", Integer.parseInt(currentPage));
                paramsMap.put("recordNumber", String.valueOf(commMap.recordNumber));
            }
            var billsDetailUrl = "https://nper.cmbc.com.cn/pweb/ActTrsQry.do";
            var billsDetail = requestUrlByPost(billsDetailUrl, paramsMap);
            var month = beginDate.substring(0,7);
            logger.info("民生银行借记卡交易流水，taskKey:{},月份：{}，本月第{}页",
                context.get(LUA_TASK_KEY),month,Integer.parseInt(currentPage));
            storeDataToFile(context, billsDetail,
                "借_"+debitCardNumber+"_bill_shopping_sheets_"+month+"_"+ Integer.parseInt(currentPage)+".html")
            Integer.parseInt(currentPage++);
            var billsDetailMap =  JSON.parse(billsDetail);
            var recordNumber = billsDetailMap.recordNumber;
            commMap.put("recordNumber", recordNumber);
            var pageNumber =  billsDetailMap.pageNumber;
            commMap.put("pageNumber", pageNumber);
            var currentDetailList = billsDetailMap.List;
            if(null == currentDetailList || currentDetailList.size() <= 0 || Integer.parseInt(currentPage) > pageNumber + 1){
                break;
            }else{
                for each(var payMap in currentDetailList){
                    number=number+1;
                    billAllData.getShoppingSheets().add(getExpenseDebit(payMap, ++orderIndex));
                }
            }
        }
        if(number>0){
            debitData.getBills().add(billAllData);
        }
    } catch (e) {
        logger.error("CMBC taskKey:{}, 保存借记卡交易流水信息出错:{}",context.get(LUA_TASK_KEY),beginDate,endDate, e);
        statCaughtException(context, e);
    }
}

//交易详情 -- 借记卡
function getExpenseDebit(payMap, orderIndex) {
    var expense = new Expense();
    try {
        expense.setId(UUID.randomUUID().toString());
        var balance = payMap.Balance.toString();
        expense.setBalance(new BigDecimal(balance)); //余额
        var description = payMap.Remark;
        expense.setDescription(description==null ? "" : description.replace(" ", ""));    //描述
        expense.setCardNum(commMap.cardNum); //卡号后四位
        var TransDate = payMap.TransDate;
        var trans_date = TimeUtil.getTimeStr(TimeUtil.getTime(TransDate, "yyyyMMdd"),"yyyy-MM-dd HH:mm:ss");
        expense.setTransDate(yyyy_MM_dd_HH_mm_ss_PARSER.parse(trans_date));  //交易时间.格式为yyyy-MM-dd HH:mm:ss
        expense.setPostDate(yyyy_MM_dd_PARSER.parse(trans_date));
        var channel = payMap.Channel;
        expense.setTransChannel(channel);   //交易通道
        expense.setOrderIndex(orderIndex);   //排序
        var amount_money = payMap.Amount;
        var amountMoneyBD = new BigDecimal(amount_money).multiply(new BigDecimal("-1"));
        expense.setAmountMoney(amountMoneyBD);   //消费金额
        expense.setCategory(CategoryUtil.getCreditCategory("COMM", description, expense.getAmountMoney().toString()));
        var opposite_bank = payMap.PayeeOpBankNo;
        expense.setOppositeBank(opposite_bank);              //对方银行
        var opposite_card_no = payMap.PayeeAc;
        expense.setOppositeCardNo(opposite_card_no);         //对方卡号
        var name_on_opposite_card = payMap.PayeeNm;
        expense.setNameOnOppositeCard(name_on_opposite_card);//对方持卡人
        expense.setCurrencyType("CNY");
    } catch (e) {
        logger.error("民生借记卡getExpense()方法解析账单流水详情时出错，taskKey:{}, e:{}", context.get(LUA_TASK_KEY), e);
        statCaughtException(context, e);
    }
    return expense;
}

//存款信息解析
function getDeposits(depositsDetailMap){
    var de = new CreditCardTimeDeposit();
    var termName =  depositsDetailMap.TermName; //六月
    var interestStr =  depositsDetailMap.Rate;   //利率
    var df=new DecimalFormat("###,##0.0######"); //0.0140000
    var interest = df.format(new BigDecimal(interestStr).divide(new BigDecimal("100")));
    de.setInterest(new BigDecimal(interest));

    var balance =  depositsDetailMap.Balance; //金额
    de.setBalance(new BigDecimal(balance));

    var currency_type =  depositsDetailMap.Currency; //币种
    de.setCurrencyType(currency_type);

    var deposit_type =  depositsDetailMap.SaveTypeName;//定期类型(如:整存整取）
    de.setDepositType(deposit_type);
    if("活期" == deposit_type){
        var open_date = depositsDetailMap.OpenDate;
        if(undefined !== open_date){
            //20160428
            var openDateStr = TimeUtil.getTimeStr(TimeUtil.getTime(open_date, "yyyyMMdd"), "yyyy-MM-dd");
            debitData.setOpenTime(yyyy_MM_dd_PARSER.parse(openDateStr));

        }
    }
    var BeginDate =  depositsDetailMap.BeginDate; //计息日期.格式yyyy-MM-dd   接收格式  20170602
    var deposit_date = TimeUtil.getTimeStr(TimeUtil.getTime(BeginDate, "yyyyMMdd"), "yyyy-MM-dd");
    de.setDepositDate(yyyy_MM_dd_PARSER.parse(deposit_date));

    var ExpireDate =  depositsDetailMap.ExpireDate; //到期日期.格式yyyy-MM-dd   接收格式  20170602
    if(!"".equals(ExpireDate)){
        var due_date = TimeUtil.getTimeStr(TimeUtil.getTime(ExpireDate, "yyyyMMdd"), "yyyy-MM-dd");
        de.setDueDate(yyyy_MM_dd_PARSER.parse(due_date));
    }

    var period_unit = "";//存期单位
    if(termName.contains("天")){
        period_unit = "DAY";
    }else if(termName.contains("月")){
        period_unit = "MONTH";
    }else if(termName.contains("年")){
        period_unit = "YEAR";
    }
    if(!"".equals(termName)){
        de.setPeriod(getPeriod(termName));
    }else{
        de.setPeriod(null);
    }
    de.setPeriodUnit(period_unit);
    debitData.getDeposits().add(de);
}

function getInstallmentsFromExpense(expense, billAllData) {
    try {
        var remark = expense.getDescription();
        if (null !== remark && !"".equals(remark) && remark.contains("第") && remark.contains("共") && remark.contains("期") && checkIfContainsNum(remark)) {
            //账单分期 每月分摊本金 (第6期共6期)   账单分期 每月分摊本金 &#40;第3期共6期
            //账单分期 手续费 &#40;第3期共6期      分期付款手续费 支付网关分24期 (第23期共24期)
            //现金分期24期商品 第2期共24期         分期付款手续费 现金分期24期商品 第2期共24期
            var remarkStr1 = remark.substring(remark.indexOf("第")); //第3期共6期
            var current_month = remarkStr1.substring(remarkStr1.indexOf("第") + 1, remarkStr1.indexOf("期"));
            var remarkStr2 = remark.substring(remark.indexOf("共"));
            var total_month = remarkStr2.substring(remarkStr2.indexOf("共") + 1, remarkStr2.indexOf("期"));
            var insList = billAllData.getInstallments();
            var ins = null;
            for each(var singleIns  in insList){
                var desc = singleIns.getInstallmentDesc();
                var feeDesc = singleIns.getHandingfeeDesc();
                if ((!equals("", desc) && null !== desc) || (!equals("", feeDesc) && null !== feeDesc)) {
                    if (!"".equals(feeDesc) && null !== feeDesc) {
                        desc = feeDesc;
                    }
                    var sameDesc = desc.substring(0, 3).equals(remark.substring(0, 3));
                    var desc1 = desc.substring(0, 2);
                    var desc2 = remark.substring(0, 2);
                    var condition = false;
                    if (("每月".equals(desc1) && "利息".equals(desc2)) || ("每月".equals(desc2) && "利息".equals(desc1))||
                        (remark.contains("手续费") && !desc.contains("手续费"))||(!desc.contains("手续费") && remark.contains("手续费")) ) {
                        condition = true;
                    }
                    if (Integer.valueOf(current_month) == singleIns.getCurrentMonth() && Integer.valueOf(total_month)
                        == singleIns.getTotalMonth() && (sameDesc || condition)) {
                        ins = singleIns;
                    }
                }
            }
            if (null == ins) {
                ins = new Installment();
                ins.setBillId(UUID.randomUUID().toString());
                billAllData.getInstallments().add(ins);
            }
            //remark.contains("本金")||(remark.contains("支付网关分") && remark.contains("手续费")==false)
            if (remark.contains("手续费") == false && remark.contains("利息") == false) {
                ins.setShoppingsheetId(expense.getId());
                ins.setTransDate(expense.getTransDate());
                ins.setPostDate(expense.getPostDate());
                var installment_type = "";
                if (remark.contains("账单")) {
                    installment_type = "BILL";
                } else if (remark.contains("自由")) {
                    installment_type = "CONSUME";
                } else if (remark.contains("自动")) {
                    installment_type = "CONSUME";
                } else if (remark.contains("现金") || remark.contains("万用金")) {
                    installment_type = "CASH";
                } else {
                    installment_type = "CONSUME";
                }
                ins.setInstallmentType(installment_type);
                ins.setCurrentMonth(Integer.valueOf(current_month));
                ins.setTotalMonth(Integer.valueOf(total_month));
                ins.setCurrencyType(expense.getCurrencyType());
                ins.setAmountMoney(expense.getAmountMoney());
                ins.setInstallmentDesc(remark);
                ins.setTransferFee(null);

            } else if (remark.contains("手续费") || remark.contains("利息")) {
                var installment_type = "";
                if (remark.contains("账单")) {
                    installment_type = "BILL";
                } else if (remark.contains("自由")) {
                    installment_type = "CONSUME";
                } else if (remark.contains("自动")) {
                    installment_type = "CONSUME";
                } else if (remark.contains("现金") || remark.contains("万用金")) {
                    installment_type = "CASH";
                } else {
                    installment_type = "CONSUME";
                }
                ins.setInstallmentType(installment_type);
                ins.setHandingFee(expense.getAmountMoney()); //本期手续费
                ins.setHandingfeeDesc(remark); //分期手续费描述
                ins.setCurrentMonth(Integer.valueOf(current_month));
                ins.setTotalMonth(Integer.valueOf(total_month));
                ins.setCurrencyType(expense.getCurrencyType());
            }

        }
    } catch (e) {
        logger.error("CMBC taskKey:{} getInstallmentsFromExpense 方法中发生异常：{}",context.get(LUA_TASK_KEY),e);
    }
}

//抓取并保存已出账单详情
function saveDoneBillsDetail(billAllData ,billDate, i) {
    try {
        var currentPage = 1;
        var number = 0;
        var orderIndex = 0;
        var paramsMap = new HashMap();
        paramsMap.put("CreditAcType", commMap.creditAcType);
        paramsMap.put("CurrencyFlag", "L");
        paramsMap.put("BillDate", billDate);
        paramsMap.put("BillDay",  creditBillDay);
        paramsMap.put("AcNo",  commMap.AcNo);
        paramsMap.put("uri", "/pweb/CreditBillQry.do");
        paramsMap.put("currentIndex", "0");  //int 转成 String
        paramsMap.put("BillFlag", "1");
        if(i>5){
            paramsMap.put("BillSixQry", "BillSixQry");
        }
        while(true){

            if(Integer.parseInt(currentPage) > 1){
                paramsMap.put("currentIndex", (Integer.parseInt(currentPage)-1)*10);
                paramsMap.put("pageNo", Integer.parseInt(currentPage));
                paramsMap.put("recordNumber", commMap.recordNumber);
            }
            var doneBillDetailUrl = "https://nper.cmbc.com.cn/pweb/CreditBillQry.do";
            var doneBillDetail = requestUrlByPost(doneBillDetailUrl, paramsMap);
            if(null == doneBillDetail || "".equals(doneBillDetail)){
                logger.info("民生银行taskKey:{},账单时间：{},已出账单未找到符合条件的详情记录", context.get(LUA_TASK_KEY),billDate);
                break;
            }else{
                var doneBillDetailMap =  JSON.parse(doneBillDetail);
                var errorMsg = doneBillDetailMap.errmsg;
                if(null != errorMsg && !"".equals(errorMsg)){
                    logger.info("民生银行已出账单详情，taskKey:{}," +
                        "账单时间：{},本月第{}页,已出账单未找到符合条件的详情记录,页面信息：{}",
                        context.get(LUA_TASK_KEY),billDate,Integer.parseInt(currentPage),errorMsg);
                    storeDataToFile(context, doneBillDetail,
                        "信_"+Integer.parseInt(indexOfCreditCard)+"_bill_shopping_sheets_"+billDate+"_"+Integer.parseInt(currentPage)+".html")
                    break;
                }else{
                    logger.info("民生银行已出账单详情，taskKey:{}," +
                        "账单时间：{},本月第{}页",context.get(LUA_TASK_KEY),billDate,Integer.parseInt(currentPage));
                    storeDataToFile(context, doneBillDetail,
                        "信_"+Integer.parseInt(indexOfCreditCard)+"_bill_shopping_sheets_"+billDate+"_"+Integer.parseInt(currentPage)+".html")
                    Integer.parseInt(currentPage++);
                    var recordNumber = doneBillDetailMap.recordNumber;
                    commMap.put("recordNumber", recordNumber);
                    var pageNumber =  doneBillDetailMap.pageNumber;
                    var currentPayRecordsDetail =  doneBillDetailMap.List;
                    if(null == currentPayRecordsDetail || currentPayRecordsDetail.size()==0 || Integer.parseInt(currentPage) > pageNumber + 1){
                        break;
                    }else{
                        for each(var payMap in currentPayRecordsDetail){
                            number = number+1;
                            var expense = getExpenseCredit(payMap, ++orderIndex);
                            billAllData.getShoppingSheets().add(expense);
                            getInstallmentsFromExpense(expense,billAllData);
                        }
                    }
                }
            }
        }
        if(number>0){
            creditCardAllData.getBills().add(billAllData);
        }
    } catch (e) {
        logger.error("CMBC taskKey:{},已出账单详情解析时出错，账单时间：{},错误信息:{}",context.get(LUA_TASK_KEY),billDate, e);
        statCaughtException(context, e);
    }
}

//消费信息  -- 信用卡
function getExpenseCredit(payMap, orderIndex) {
    var expense = new Expense();
    expense.setNameOnOppositeCard("");
    expense.setOppositeBank("");
    expense.setOppositeCardNo("");
    expense.setRemark("");
    expense.setTransAddr("");
    expense.setTransChannel("");
    expense.setTransMethod("");
    try {
        expense.setId(UUID.randomUUID().toString());
        var description = payMap.TransDescribe;  //交易描述
        expense.setCardNum(payMap.AcNoRearFour);  //卡号后四位
        var recordDate = payMap.RecordDate;
        expense.setPostDate(yyyy_MM_dd_PARSER.parse(recordDate));    //记账日期  格式为yyyy-MM-dd
        expense.setAmountMoney(payMap.TransAmt);   //消费金额
        //通过消费金额TransAmt计算last_payment：TransAmt值为负数的相加
        if(payMap.TransAmt.compareTo(new BigDecimal(0))==-1){
            if(null==lastPayment){
                lastPayment = payMap.TransAmt;
            }else{
                lastPayment = payMap.TransAmt.add(lastPayment);
            }
        }
        expense.setCurrencyType(payMap.Currency);   //币种
        expense.setDescription(description==null ? "" : description.replace(" ", ""));  //交易描述
        expense.setCategory(CategoryUtil.getCreditCategory("COMM", description, expense.getAmountMoney().toString()));
        expense.setOrderIndex(orderIndex);
        expense.setBalance(null);

        var consumeDate =  payMap.ConsumeDate; //交易时间.格式为yyyy-MM-dd HH:mm:ss  2017 07 31  2017 08 03
        logger.info("CMBC task : {},首次获取的consumeDate：{}", context.get(LUA_TASK_KEY), consumeDate);
        //处理消费日期和记账日期的关系
        var year = recordDate.substring(0,4);
        consumeDate = year+consumeDate;
        var sdf = new SimpleDateFormat("yyyyMMdd");
        var sdf1 = new SimpleDateFormat("yyyy/MM/dd");
        var sdf2 = new SimpleDateFormat("yyyy-MM-dd");
        var date1 = sdf.parse(consumeDate)
        var date2 = sdf2.parse(recordDate)
        //如果处理之后的消费日期在记账日期之后,消费日期年份-1
        if(date2.before(date1)){
            year = Integer.parseInt(year);
            year = year-1;
            consumeDate = year+consumeDate.substring(4);
        }
        var transeDate = TimeUtil.getTimeStr(TimeUtil.getTime(consumeDate, "yyyyMMdd"), "yyyy-MM-dd HH:mm:ss");
        expense.setTransDate(yyyy_MM_dd_PARSER.parse(transeDate));
    } catch (e) {
        logger.error("CMBC taskKey:{}，解析第{}页消费信息详情时出错:{}", context.get(LUA_TASK_KEY),orderIndex, e);
        statCaughtException(context, e);
    }
    return expense;
}

function getUndoneBillData() {
    var billAllData = new BillAllData();
    var billMonth = getBillMonth("yyyy-MM");
    billAllData.setBillMonth(billMonth);
    try {
        //未出账单中，billAllDate无数据，只有shopping中有数据
        billAllData.setBillType("UNDONE");
        billAllData.setBankName("民生银行");
        billAllData.setBillId(UUID.randomUUID().toString());
        var billTime = getBillTime("yyyy-MM");
        billAllData.setBillMonth(billTime);
        var billDate = new StringBuilder().append(billTime).append("-").append(creditBillDay);
        billAllData.setBillDate(yyyy_MM_dd_PARSER.parse(billDate.toString()));
        billAllData.setPaymentDueDate(null);
        billAllData.setInterest(null);
        billAllData.setLastPayment(null);
        billAllData.setMinPayment(null);
        billAllData.setCreditLimit(creditCardAllData.getCreditLimit());
        billAllData.setCashLimit(creditCardAllData.getCashLimit());
        billAllData.setInstallments(new ArrayList());
        //美元相关
        billAllData.setUsdNewBalance(null);
        billAllData.setUsdMinPayment(null);
        billAllData.setUsdLastBalance(null);
        billAllData.setUsdLastPayment(null);
        billAllData.setUsdNewCharges(null);
        billAllData.setUsdInterest(null);
        billAllData.setUsdCreditLimit(null);
        billAllData.setUsdCashLimit(null);
        //账单详情
        billAllData.setShoppingSheets(new ArrayList());
    } catch (e) {
        logger.error("CMBC taskKey:{},信用卡解析未出账单时出错:{}", context.get(LUA_TASK_KEY),e);
        statCaughtException(context, e);
    }
    return billAllData;
}
//单元测试所用
function getUndoneBillDataTest(billMonth) {
    var billAllData = new BillAllData();
    billAllData.setBillMonth(billMonth);
    try {
        //未出账单中，billAllDate无数据，只有shopping中有数据
        billAllData.setBillType("UNDONE");
        billAllData.setBankName("民生银行");
        billAllData.setBillId(UUID.randomUUID().toString());
        var billDate = new StringBuilder().append(billMonth).append("-").append(creditBillDay);
        billAllData.setBillDate(yyyy_MM_dd_PARSER.parse(billDate.toString()));
        billAllData.setPaymentDueDate(null);
        billAllData.setInterest(null);
        billAllData.setLastPayment(null);
        billAllData.setMinPayment(null);
        billAllData.setCreditLimit(creditCardAllData.getCreditLimit());
        billAllData.setCashLimit(creditCardAllData.getCashLimit());
        billAllData.setInstallments(new ArrayList());
        //美元相关
        billAllData.setUsdNewBalance(null);
        billAllData.setUsdMinPayment(null);
        billAllData.setUsdLastBalance(null);
        billAllData.setUsdLastPayment(null);
        billAllData.setUsdNewCharges(null);
        billAllData.setUsdInterest(null);
        billAllData.setUsdCreditLimit(null);
        billAllData.setUsdCashLimit(null);
        //账单详情
        billAllData.setShoppingSheets(new ArrayList());
    } catch (e) {
        logger.error("CMBC taskKey:{},信用卡解析未出账单时出错:{}", context.get(LUA_TASK_KEY),e);
        statCaughtException(context, e);
    }
    return billAllData;
}

//获取账单日期
function getBillTime(format)   {
    var cal = Calendar.getInstance();
    var day = cal.get(Calendar.DAY_OF_MONTH);
    if(day > Integer.parseInt(  commMap.BillDay)){
        cal.add(Calendar.MONTH, 1);
    }
    return DateFormatUtils.format(cal.getTime(), format);
}

//初始化一个billMonth防止字段为空
function getBillMonth(format){
    var cal = Calendar.getInstance();
    cal.add(Calendar.MONTH, 1);
    return DateFormatUtils.format(cal.getTime(), format);
}

//获取查询日期  格式 1705 （年月） 六个月，包含本月
function getSixMonth(billDay )  {

    var dfdate1 = new SimpleDateFormat("dd");
    var now = dfdate1.format(new Date());

    var lst = new ArrayList();
    var calendar = new GregorianCalendar();
    var dfdate = new SimpleDateFormat("yyMM");

    if(Integer.parseInt(billDay) < Integer.parseInt(now)){
        for(var i = 0; i < 12; i++){
            calendar.setTime(new Date());
            calendar.add(Calendar.MONTH, -1 * i);
            lst.add(dfdate.format(calendar.getTime()));
        }
    }else{
        for (var i = 1; i < 13; i++) {
            calendar.setTime(new Date());
            calendar.add(Calendar.MONTH, -1 * i);
            lst.add(dfdate.format(calendar.getTime()));
        }
    }
    return lst;
}

function getPeriod(termName){
    var period;
    switch(termName){
        case "三月":
            period = 3; break;
        case "六月":
            period = 6; break;
        case "一年":
            period = 1; break;
        case "三年":
            period = 3; break;
        case "五年":
            period = 5; break;
        default:
            period = 0; break;

    }
    return period;
}

//获取之前6个月的第一天:格式:2016-12-01
function getFirstSixMonthFirstDay() {

    var lst = new ArrayList();

    var calendar = new GregorianCalendar();

    var dfdate = new SimpleDateFormat("yyyy-MM-dd");

    for (var i = 0; i < 25; i++) {

        calendar.setTime(new Date());
        calendar.add(Calendar.MONTH, -1 * i);

        var gcLast = Calendar.getInstance();
        gcLast.setTime(calendar.getTime());
        gcLast.set(Calendar.DAY_OF_MONTH, 1);
        lst.add(dfdate.format(gcLast.getTime()));

    }
    var date = dfdate.format(new Date());
    var date1 = lst.get(24).substring(0, 7)+date.substring(7);
    lst.set(24, date1);

    return lst;
}

//获取之前6个月的最后一天,格式:2016-12-31,本月返回今天
function getBeforSixMonthLast() {

    var lst = new ArrayList();

    var calendar = new GregorianCalendar();

    var dfdate = new SimpleDateFormat("yyyy-MM-dd");

    for (var i = -1; i < 24; i++) {

        calendar.setTime(new Date());
        calendar.add(Calendar.MONTH, -1 * i);

        var gcLast = Calendar.getInstance();
        gcLast.setTime(calendar.getTime());
        gcLast.set(Calendar.DATE, 1);
        gcLast.add(Calendar.DATE, -1);
        if (gcLast.getTime().after(new Date())) {
            lst.add(dfdate.format(new Date()));
        } else {
            lst.add(dfdate.format(gcLast.getTime()));
        }

    }

    return lst;
}

//判断字符串中是否包含字母 （用于判断分期数据的条件中）
function checkIfContainsNum(str) {
    var isDigit = false;
    var regNumber = /\d+/; //验证0-9的任意数字最少出现1次。
    if (regNumber.test(str)) {
        isDigit = true;
    }
    return isDigit;
}

var luaFuncs = {

    clickLoginButtonAndGetLoginResult:function (id) {
        var map = new HashMap();
        map.put("method","clickLoginButtonAndGetLoginResult");
        return sendAndReceive(map)
    },
    input_minsheng_pwd:function (password){
        var map = new HashMap();
        map.put("method","input_minsheng_pwd");
        map.put("password",password);
        return sendAndReceive(map);
    },
    token_check_minsheng:function(){
        var map = new HashMap();
        map.put("method","token_check_minsheng");
        return sendAndReceive(map);
    },
    getHtml2:function () {
        var map = new HashMap();
        map.put("method","getHtml2");
        return sendAndReceive(map);
    },
    saveHtmlAndImageFunc:function (name) {
        var map = new HashMap();
        map.put("name",name);
        map.put("method","saveHtmlAndImageFunc");
        return sendAndReceive(map);
    },
    checkIfInput : function(id,value){
        var map = new LinkedHashMap();
        map.put("method", "checkIfInput");
        map.put("id", id);
        map.put("value", value);
        return Boolean.valueOf(sendAndReceive(map));
    }

}